﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Data.Sql;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using Inference;

namespace Frames
{
    public enum Modes { CREATE_SLOT, EDIT_SLOT, CREATE_FRAME, EDIT_FRAME };
    public partial class FrameForm : Form
    {
        public FrameForm(/*bool rbc_checked*/  Modes _mode, int _FrameID, string _NewFrameName, int _FrameType, int _X, int _Y)
        {
            InitializeComponent();
            par = new Parameter(_mode, _FrameID, _NewFrameName, _FrameType, _X, _Y);
        }

        public class Parameter
        {
            public Modes mode;
            public int FrameID;
            public string NewFrameName;
            // public int SlotID;
            public int FrameType;
            //public int is_aID;
            public int X, Y;


            public Parameter(Modes _mode, int _frameID, string _newFrameName, int _frameType, int _X, int _Y) // 1-ситуация, 2-сущность
            {
                mode = _mode;
                FrameID = _frameID;
                NewFrameName = _newFrameName;
                // SlotID = _SlotID;
                FrameType = _frameType;
                X = _X; Y = _Y;
            }
        }
        string ConnectionString, FrameName = "", ParentName = "";
        SqlConnection conn;
        SqlDataAdapter sadapt;
        Parameter par;
        int Is_aID = -1, FrameID, SystemSlotsCount = 0, ParentSlotsCount = 0, //в рамках какого фрейма работаем
            dragged_row_index = -1, AddedSlotID = -1, UpdatedSlotID = -1;
        Modes mode;
        SlotForm slf;
        DataTable datat_frame, datat_parent;
        Inference.TaleEntities Tale = new Inference.TaleEntities();

        private void LoadSystemSlotsToGrid()
        {
            if (par.FrameID >= 0)
            {
                SqlCommand get_frame_name = new SqlCommand("", conn);
                get_frame_name.CommandText = "select Name, Is_a from Frame where ID=" + par.FrameID.ToString();
                SqlDataReader sread = get_frame_name.ExecuteReader();
                while (sread.Read())
                {
                    label2.Text = sread.GetString(0);
                    FrameName = label2.Text;
                    try
                    {
                        Is_aID = sread.GetInt32(1);
                    }
                    catch
                    {
                        Is_aID = -1;
                    }
                }
                sread.Close();
                dgSlots.Rows.Insert(0);
                dgSlots.Rows[0].Cells[1].Value = "Имя";
                dgSlots.Rows[0].Cells[3].Value = label2.Text;
                dgSlots.Rows[/*dgSlots.Rows.Count - 1*/0].Cells[0].Style.BackColor = Color.LightBlue;
                string Is_aName = "NULL";
                if (Is_aID != -1)
                {
                    SqlCommand get_is_a_name = new SqlCommand("", conn);
                    get_is_a_name.CommandText = "select Name from Frame where ID=" + Is_aID;
                    sread = get_is_a_name.ExecuteReader();
                    if (sread.Read())
                    {
                        Is_aName = sread.GetString(0);
                    }
                    sread.Close();
                }
                dgSlots.Rows.Insert(1);// Add();
                dgSlots.Rows[1].Cells[1].Value = "Is a";
                dgSlots.Rows[1].Cells[3].Value = Is_aName;
                dgSlots.Rows[1].Cells[0].Style.BackColor = Color.LightBlue;
            }
        }

        public DataTable LoadSlotsFromDB(SqlConnection conn, int FrameID)
        {
            DataTable datat;
            if (FrameID >= 0)
            {
                SqlCommand get_frame_slots = new SqlCommand("", conn);
                get_frame_slots.CommandText = "select * from Slot where FrameID=" + FrameID.ToString() +
                            " order by Number asc";
                sadapt = new SqlDataAdapter(get_frame_slots);
                datat = new DataTable();
                sadapt.Fill(datat);
                //dgSlots.DataSource = datat;                                
            }
            else
            {
                MessageBox.Show("Не удалось получить информацию о фрейме!", "Ошибка");
                return null;
            }
            return datat;
        }

        private void LoadProducts(int SlotID, int grid_line)
        {
            var prod_facts = from p in Tale.ViewProductions where (p.SlotID == SlotID) orderby (p.Type) orderby (p.ProductionID) select p;//  group p by p.ProductionID;
            int i = -1, ins_i = -1, fact_in_prod_i = 0;
            bool if_fisrt_in_conc = true;
            foreach (Inference.ViewProductions pr_f in prod_facts)
            {
                if (i != pr_f.ProductionID) // началась новая продукция
                {
                    if (i != -1 && pr_f.Type == 1)
                        dgSlots.Rows[grid_line].Cells[dgSlots.Columns.Count - 1].Value += "; ЕСЛИ ";
                    else if (i != -1 && pr_f.Type == 3)
                        dgSlots.Rows[grid_line].Cells[dgSlots.Columns.Count - 1].Value += "; ";
                    else if (i == -1 && pr_f.Type == 1)
                        dgSlots.Rows[grid_line].Cells[dgSlots.Columns.Count - 1].Value += "ЕСЛИ ";
                    i = pr_f.ProductionID;
                    ins_i++;
                    fact_in_prod_i = 0;
                    if_fisrt_in_conc = true;
                }
                string str = "";
                var comp_value = Tale.DValues.Where(v => v.ID == pr_f.ValueID).First();
                string comp_slot_name = "";
                List<Slot> chain_slots = CheckIf.GetProductionChain((int)pr_f.Place, (int)pr_f.CompSlotID);//Tale.Slot.Where(v => v.ID == pr_f.CompSlotID).First();
                foreach (Slot sl in chain_slots)
                {
                    comp_slot_name += "'" + sl.Name + "'.";
                }
                if (comp_slot_name != "")
                    comp_slot_name = comp_slot_name.Substring(0, comp_slot_name.Length - 1);
                if (fact_in_prod_i > 0 && pr_f.Type != 2)
                    str = " И";
                else if (if_fisrt_in_conc && pr_f.Type == 2 && fact_in_prod_i > 0)
                {
                    str += " ТО ";
                    if_fisrt_in_conc = false;
                }
                else if (!if_fisrt_in_conc && fact_in_prod_i > 0 && pr_f.Type == 2)
                {
                    str += ", ";
                }

                str += " " + comp_slot_name +
                    (pr_f.Negation ? " != " : " = ") + comp_value.Value + " ";
                // if (pr_f.Type == 1)
                {
                    dgSlots.Rows[grid_line].Cells[dgSlots.Columns.Count - 1].Value += str;
                }
                //else if (pr_f.Type == 2)
                //{
                //    dgSlots.Rows[grid_line].Cells[dgSlots.Columns.Count - 1].Value += str;
                //}
                fact_in_prod_i++;
                //  }
            }
        }

        private void LoadFrameSlotsToGrid(DataTable datat)
        {
            this.dgSlots.SelectionChanged -= new System.EventHandler(this.dgSlots_SelectionChanged);
            dgSlots.Columns.Clear();
            for (int i = 0; i < datat.Columns.Count; i++)
            {
                dgSlots.Columns.Add("dgSlots_col_" + datat.Columns[i].ColumnName, datat.Columns[i].ColumnName);
                dgSlots.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
                dgSlots.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                switch (datat.Columns[i].ColumnName)
                {
                    case "Name": dgSlots.Columns[i].HeaderText = "Имя"; break;
                    case "Domain": dgSlots.Columns[i].HeaderText = "Домен"; break;
                    case "DefaultValue": dgSlots.Columns[i].HeaderText = "Задание отсутствия"; break;
                    case "AllowNull": dgSlots.Columns[i].HeaderText = "Допускается ли \"Не знаю\""; break;
                    case "FrameID":
                    case "DomainType":
                    case "Number":
                        dgSlots.Columns[i].Visible = false; break;
                    case "Question": dgSlots.Columns[i].HeaderText = "Вопрос"; break;
                    case "ID": dgSlots.Columns[i].HeaderText = ""; break;
                    case "Inheritance": dgSlots.Columns[i].HeaderText = "Тип наследования"; break;
                }
                //if (i == 0)
                //    dgSlots.Columns[i].Visible = false;                
            }
            foreach (DataRow dr in datat.Rows)
            {
                //if (dr.ItemArray[1].ToString().Trim().ToLower() != "имя фрейма")
                {
                    dgSlots.Rows.Add(/*dr.ItemArray*/);
                    for (int i = 0; i < dr.ItemArray.Length; i++)
                    {
                        if (dgSlots.Columns[i].HeaderText == "Допускается ли \"Не знаю\"")
                        {
                            if ((bool)dr.ItemArray[i])
                                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = "Да";
                            else
                                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = "Нет";
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Тип наследования")
                        {
                            if ((int)dr.ItemArray[i] == 1)
                                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = "Override";
                            else
                                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = "Same";
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Домен")
                        {
                            if (dr.ItemArray[9] != DBNull.Value && (int)dr.ItemArray[9] > 0)
                            {
                                int dom_ind = (int)dr.ItemArray[9];
                                var dom = Tale.Frame.Where(v => v.ID == dom_ind);
                                if (dom.Count() > 0)
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dom.First().Name;
                                else
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dr.ItemArray[9];
                            }
                            else
                            {
                                int dom_ind = (int)dr.ItemArray[2];
                                var dom = Tale.Domains.Where(v => v.ID == dom_ind);
                                if (dom.Count() > 0)
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dom.First().Name;
                                else
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dr.ItemArray[2];
                            }
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Задание отсутствия")
                        {
                            int dom_ind = 0;
                            if (dr.ItemArray[3]!=DBNull.Value)
                                dom_ind = (int)dr.ItemArray[3];
                            if (dr.ItemArray[9] != DBNull.Value && (int)dr.ItemArray[9] > 0)
                            {
                                var def_val = Tale.Frame.Where(v => v.ID == dom_ind);
                                if (def_val.Count() > 0)
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = def_val.First().Name;
                                else
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dr.ItemArray[3];
                            }
                            else
                            {
                                var def_val = Tale.DValues.Where(v => v.ID == dom_ind);
                                if (def_val.Count() > 0)
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = def_val.First().Value;
                                else
                                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dr.ItemArray[3];
                            }
                        }
                        else
                            dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[i].Value = dr.ItemArray[i];
                    }

                    Color highlight_color;
                    if (CheckIf.SlotIsInherited(dr.ItemArray[1].ToString(), FrameName))
                        highlight_color = Color.PaleGoldenrod;
                    else
                        highlight_color = Color.PaleGreen;
                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.BackColor = highlight_color;
                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.ForeColor = highlight_color;
                    Color cl = dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.SelectionBackColor;
                    dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                }
                if (dr.ItemArray[1].ToString().Trim().ToLower() == "имя фрейма")
                {
                    dgSlots.Rows[dgSlots.Rows.Count - 1].Visible = false;
                }
            }
            dgSlots.Columns.Add("dgSlots_col_prods", "Продукционный маркер");
            dgSlots.Columns[dgSlots.Columns.Count - 1].SortMode = DataGridViewColumnSortMode.NotSortable;
            dgSlots.Columns[dgSlots.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            int j = 0;
            for (int i = dgSlots.Rows.Count - datat.Rows.Count; i < dgSlots.Rows.Count; i++)
            {
                LoadProducts((int)datat.Rows[j].ItemArray[0], i);
                j++;
            }
            this.dgSlots.SelectionChanged += new System.EventHandler(this.dgSlots_SelectionChanged);

        }

        private int GetLastFrameID()
        {
            int temp = -1;
            SqlCommand get_frame_id = new SqlCommand("", conn);
            get_frame_id.CommandText = "select ID from Frame where Name=\'" + FrameName + "\'";
            SqlDataReader sread = get_frame_id.ExecuteReader();
            while (sread.Read())
                temp = sread.GetInt32(0);
            sread.Close();
            return temp;
        }

        private void CreateParentSlots(int frameID)
        {
            SqlCommand create_slot;
            for (int i = 0; i < datat_parent.Rows.Count; i++)
            {
                create_slot = new SqlCommand("", conn);
                create_slot.CommandText = "insert into Slot (Name,Domain,DefaultValue, AllowNull, " +
                "FrameID, Question,Number, Inheritance, DomainType) values (\'" +
                datat_parent.Rows[i].ItemArray[1].ToString() + "\', ";
                string str = "";
                for (int j = 2; j <= 3; j++)
                {
                    if (datat_parent.Rows[i].ItemArray[j] != DBNull.Value)
                        str += datat_parent.Rows[i].ItemArray[j].ToString() + ", ";
                    else
                        str += "NULL, ";
                }
                create_slot.CommandText += str;
                create_slot.CommandText += (((bool)(datat_parent.Rows[i].ItemArray[4])) ? "1" : "0") + ", " +
                frameID.ToString() + ", \'" +
                datat_parent.Rows[i].ItemArray[6].ToString() + "\', " +
                datat_parent.Rows[i].ItemArray[7].ToString() + ", " +
                datat_parent.Rows[i].ItemArray[8].ToString() + ", ";
                if (datat_parent.Rows[i].ItemArray[9] != DBNull.Value)
                    create_slot.CommandText += datat_parent.Rows[i].ItemArray[9].ToString();
                else
                    create_slot.CommandText += "NULL";
                create_slot.CommandText += ")";
                create_slot.ExecuteNonQuery();
            }
        }

        private string GenerateFrameName()
        {
            // MessageBox.Show("Генерацияаа имении фреймааа");
            return "";
        }
        private int GetPlaceInChildFrame(string parent_place_name)
        {
            int temp = -1;
            SqlCommand get_slot_id = new SqlCommand("", conn);
            get_slot_id.CommandText = "select ID from Slot where frameID=" + FrameID.ToString()
                + " and Name=\'" + parent_place_name + "\'"; // and Number=" + SlotNumber.ToString();
            SqlDataReader sread = get_slot_id.ExecuteReader();
            while (sread.Read())
            {
                try
                {
                    temp = sread.GetInt32(0);
                }
                catch
                { temp = -1; }
            }
            sread.Close();
            return temp;
        }

        private int GetMaxTableID(string table_name)
        {
            int temp = -1;
            SqlCommand get_id = new SqlCommand("", conn);
            get_id.CommandText = "select max(ID) from " + table_name;
            SqlDataReader sread = get_id.ExecuteReader();
            while (sread.Read())
            {
                try
                {
                    temp = sread.GetInt32(0);
                }
                catch { }
            }
            sread.Close();
            return temp;
        }

        private void CopyParentProducts()
        {
            int parent_slot_id = -1, child_slot_id = -1, child_place = -1, child_comp_slot_id = -1, fact_id = -1;
            string query = "";
            for (int i = 0; i < datat_parent.Rows.Count; i++)
            {
                parent_slot_id = (int)datat_parent.Rows[i].ItemArray[0];
                child_slot_id = (int)datat_frame.Rows[i].ItemArray[0];
                var prod_facts = from p in Tale.ViewProductions where (p.SlotID == parent_slot_id) orderby (p.Type) orderby (p.ProductionID) select p;
                // 1,7,10 dom
                foreach (Inference.ViewProductions pp in prod_facts)
                {
                    var parent_place = Tale.Slot.Where(v => v.ID == pp.Place).First();
                    if (parent_place != null)
                        child_place = GetPlaceInChildFrame(parent_place.Name);
                    if (pp.CompSlotID == pp.Place) // place изменится, тк это слот родит. фрейма
                        child_comp_slot_id = child_place;
                    else
                        child_comp_slot_id = pp.CompSlotID; // слот в субфрейме тот же самый
                    query = "insert into Fact (SlotID, ValueID, Negation, CompSlotID, Place) values (" +
                            child_slot_id.ToString() + ", " + pp.ValueID + ", " +
                            (pp.Negation ? "1" : "0") + ", " + child_comp_slot_id.ToString() + ", " + child_place.ToString() + ")";
                    SqlCommand insert_comm = new SqlCommand("", conn);
                    insert_comm.CommandText = query;
                    insert_comm.ExecuteNonQuery();
                    fact_id = GetMaxTableID("Fact");
                    query = "insert into ProductionFact (FactID, ProductionID, Type, Number) values (" +
                            fact_id.ToString() + ", " + pp.ProductionID.ToString() + ", " + pp.Type.ToString() + ", " +
                            pp.Number.ToString() + ")";
                    insert_comm.CommandText = query;
                    insert_comm.ExecuteNonQuery();
                }
            }
        }

        private void CreateFromParent(int ParentID)
        {
            datat_parent = LoadSlotsFromDB(conn, ParentID);
            ParentSlotsCount = datat_parent.Rows.Count;
            SqlCommand get_frame_name = new SqlCommand("", conn);
            get_frame_name.CommandText = "select Name from Frame where ID=" + ParentID.ToString();
            SqlDataReader sread = get_frame_name.ExecuteReader();
            while (sread.Read())
                ParentName = sread.GetString(0);
            sread.Close();
            GenerateFrameName();
            FrameName = par.NewFrameName;
            Is_aID = ParentID;
            SqlCommand create_frame = new SqlCommand("", conn);
            create_frame.CommandText = "insert into Frame (Name, Is_a, X, Y) values (\'" +
                FrameName + "\', " +
                ParentID.ToString() + ", " +
                par.X.ToString() + ", " + par.Y.ToString() + ")";
            create_frame.ExecuteNonQuery();
            //int temp = GetLastFrameID();
            FrameID = GetLastFrameID();
            par.FrameID = FrameID;  /// !!!!!!!!!!!!!!!!!!!!!!!!
            if (FrameID >= 0)
                CreateParentSlots(FrameID);
            datat_frame = LoadSlotsFromDB(conn, FrameID);
            //CopyParentProducts();
            //return temp;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //string curr_sol_dir = System.Reflection.Assembly.GetExecutingAssembly().Location;
            //curr_sol_dir = curr_sol_dir.Replace("\\bin\\Debug\\Inference.exe", "");
            ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + Directory.GetCurrentDirectory() +
                /*curr_sol_dir*/ "\\Tale.mdf" + ";Integrated Security=True;Connect Timeout=30;User Instance=True";
            conn = new SqlConnection(ConnectionString);
            conn.Open();

            SystemSlotsCount = 2;
            if (par.mode == Modes.EDIT_FRAME)
            {
                FrameID = par.FrameID;
                datat_frame = LoadSlotsFromDB(conn, par.FrameID);
                LoadFrameSlotsToGrid(datat_frame);
                LoadSystemSlotsToGrid(); // получение Is_aID здесь уже есть.
                this.Text = "Редактирование фрейма " + FrameName;
                if (Is_aID >= 0)
                {
                    datat_parent = LoadSlotsFromDB(conn, Is_aID);
                    ParentSlotsCount = datat_parent.Rows.Count;
                }
            }
            else if (par.mode == Modes.CREATE_FRAME)
            {
                this.Text = "Создание фрейма ";
                if (par.FrameID != -1) // интерпретируем фреймID как ID родителя в случае create
                {
                    // создать слоты родительского фрейма(+зад. отсутств., +маркеры)
                    // проставить значение слота is_a
                    /*FrameID =*/
                    CreateFromParent(par.FrameID);
                }
                else if (par.FrameType == 1) // ситуация
                {
                    // ЗАПРОС мб get Ситуация ID
                    CreateFromParent(25);               // FrameID, datat_frame, datat_parent - получены здесь
                    // создать системные слоты:
                    //  имя - некоторое по умолчанию (состыковать с тривью)
                    //  is_a - null
                }
                else if (par.FrameType == 2) // сущность
                {
                    CreateFromParent(32);
                }
                // datat_frame = LoadSlotsFromDB(conn, FrameID);
                LoadFrameSlotsToGrid(datat_frame);
                label2.Text = FrameName;
                dgSlots.Rows.Insert(0, 1);
                dgSlots.Rows[0].Cells[1].Value = "Имя";
                dgSlots.Rows[0].Cells[3].Value = label2.Text;
                dgSlots.Rows[0].Cells[0].Style.BackColor = Color.LightBlue;
                dgSlots.Rows.Insert(1, 1);
                dgSlots.Rows[1].Cells[1].Value = "Is a";
                dgSlots.Rows[1].Cells[3].Value = ParentName;
                dgSlots.Rows[1].Cells[0].Style.BackColor = Color.LightBlue;
            }
            // just highlight
            int start = 0;
            if (SystemSlotsCount > 0)
                start = SystemSlotsCount;
            // !!!!!!!!
            for (int i = start; i < dgSlots.Rows.Count; i++)
            {
                if (par.FrameType == 1)
                {
                    if (i < start + ParentSlotsCount - 1)
                    {
                        dgSlots.Rows[i].Cells[0].Style.BackColor = Color.PaleGoldenrod;
                        dgSlots.Rows[i].Cells[0].Style.ForeColor = Color.PaleGoldenrod;
                        Color cl = dgSlots.Rows[i].Cells[0].Style.SelectionBackColor;
                        dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                    }
                    else
                    {
                        dgSlots.Rows[i].Cells[0].Style.BackColor = Color.PaleGreen;
                        dgSlots.Rows[i].Cells[0].Style.ForeColor = Color.PaleGreen;
                        Color cl = dgSlots.Rows[i].Cells[0].Style.SelectionBackColor;
                        //dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = cl;
                        dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                    }
                }
                else if (par.FrameType == 2)
                {
                    if (i <= start + ParentSlotsCount - 1)
                    {
                        dgSlots.Rows[i].Cells[0].Style.BackColor = Color.PaleGoldenrod;
                        dgSlots.Rows[i].Cells[0].Style.ForeColor = Color.PaleGoldenrod;
                        Color cl = dgSlots.Rows[i].Cells[0].Style.SelectionBackColor;
                        //dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = cl;
                        dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                    }
                    else
                    {
                        dgSlots.Rows[i].Cells[0].Style.BackColor = Color.PaleGreen;
                        dgSlots.Rows[i].Cells[0].Style.ForeColor = Color.PaleGreen;
                        Color cl = dgSlots.Rows[i].Cells[0].Style.SelectionBackColor;
                        //dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = cl;
                        dgSlots.Rows[i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                    }
                }
            }
            if (par.FrameType == 1 && dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[1].Value.ToString().ToLower() == "next"
                && FrameName.ToLower() != "ситуация")
            {
                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.BackColor = Color.PaleGoldenrod;
                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.ForeColor = Color.PaleGoldenrod;
                Color cl = dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.SelectionBackColor;
                //dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.SelectionForeColor = cl;
                dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
            }
        }

        private void Frame_FormClosed(object sender, FormClosedEventArgs e)
        {
            conn.Close();
        }

        private void dgSlots_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex != -1 && e.RowIndex != -1)
                if (e.RowIndex >= SystemSlotsCount && dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString().Trim().ToLower() != "имя фрейма")
                {
                    string str = "";
                    // bool parent_slot = CheckIf.SlotIsInherited(dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString(), FrameName);
                    //if (!parent_slot)
                    //{
                    //    str = "Вы действительно хотите удалить слот " + dgSlots.SelectedCells[1].Value.ToString() +
                    //               " фрейма " + FrameName + "?";
                    //}
                    //else
                    //{
                    //    str = "Данный слот пронаследован от родительского фрейма! Если его переименовать, фрейм перестанет \n" +
                    //        " наследовать от текущего фрейма-родителя! Вы действительно хотите изменить слот " + dgSlots.SelectedCells[1].Value.ToString() + "?";
                    //}
                    //DialogResult dr = MessageBox.Show(str, "Внимание", MessageBoxButtons.OKCancel);
                    //if (dr == DialogResult.OK)
                    //{
                    slf = new SlotForm(/*ConnectionString,*/ Modes.EDIT_SLOT, mode, FrameID, par.FrameType, int.Parse(dgSlots.Rows[e.RowIndex].Cells[0].Value.ToString()), -1, false);
                    DialogResult dr1 = slf.ShowDialog();
                    if (dr1 == DialogResult.OK)
                    {
                        UpdatedSlotID = int.Parse(dgSlots.Rows[e.RowIndex].Cells[0].Value.ToString());
                        var slots = Tale.Slot.Where(v => v.ID == UpdatedSlotID);
                        #region не то
                        //SqlCommand get_slot_id = new SqlCommand("", conn);
                        //get_slot_id.CommandText = "select max(ID) from Slot";
                        //SqlDataReader sread = get_slot_id.ExecuteReader();
                        //while (sread.Read())
                        //{
                        //    try
                        //    {
                        //        UpdatedSlotID = sread.GetInt32(0);
                        //    }
                        //    catch { }
                        //}
                        //sread.Close();
                        #endregion
                        if (UpdatedSlotID != -1 && slots.Count() > 0)
                        {
                            bool renamed_slot = dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString() != slots.First().Name;
                            //LoadSlotToGrid(dgSlots.SelectedCells[0].RowIndex, UpdatedSlotID, false);
                            //datat_frame = LoadSlotsFromDB(conn, FrameID);
                            if (renamed_slot)
                            {
                                string old_root_name = GetRoot(Is_aID).ToLower(), new_root_name = "";
                                // не ситуация тем же и останется
                                if (old_root_name == "ситуация")
                                {
                                    DeleteFrameFromDomain(FrameID, "Имена фреймов-ситуаций");
                                    AddFrameToDomain(FrameID, "Имена фреймов-сущностей");
                                }
                                var frames = Tale.Frame.Where(v => v.ID == FrameID);
                                try
                                {
                                    Frame frame = frames.First();
                                    frame.Is_a = null;
                                    Tale.SaveChanges();
                                    //SqlCommand delete_isa = new SqlCommand("", conn);
                                    //delete_isa = new SqlCommand("", conn);
                                    //delete_isa.CommandText = "update Frame set Is_a=NULL " +
                                    //    " where ID=" + FrameID.ToString();
                                    //delete_isa.ExecuteNonQuery();
                                }
                                catch { }
                                ParentSlotsCount = 0;
                            }
                            dgSlots.Rows.Clear();
                            datat_frame = LoadSlotsFromDB(conn, FrameID);
                            LoadFrameSlotsToGrid(datat_frame);
                            LoadSystemSlotsToGrid();
                        }
                    }
                    //}
                }
                else if (e.RowIndex == 1 && dgSlots.Rows[e.RowIndex].Cells[1].Value != null
                      && dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString().ToLower() == "is a"
                    && FrameName.Trim().ToLower()!="ситуация")
                {
                    if (Inference.CheckIf.ISACouldBeDeleted(FrameName))
                    {
                        Inference.Is_aForm isaf = new Inference.Is_aForm(FrameID, Tale, conn);
                        if (isaf.ShowDialog() == DialogResult.OK && isaf.IfLinkChanged)
                        {
                            dgSlots.Rows.Clear();
                            ParentSlotsCount = Tale.Slot.Where(s => s.FrameID == Is_aID).Count();
                            datat_frame = LoadSlotsFromDB(conn, FrameID);
                            LoadFrameSlotsToGrid(datat_frame);
                            LoadSystemSlotsToGrid();
                        }
                    }
                    else
                        MessageBox.Show("Связь Is_a не может быть удалена,\n так как слоты " +
                            "данного фрейма или их потомки используются в продукциях!", "Ошибка", MessageBoxButtons.OKCancel);
                }
            // NAME EDITIND
            //else if (e.RowIndex == 0 && dgSlots.Rows[e.RowIndex].Cells[1].Value != null
            //      && dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString().ToLower() == "имя")
            //{
            //    string header = "Редактирование " + ((par.FrameType == 1) ? "фрейма-ситуации" : "фрейма-сущности") +
            //        " \"" + FrameName + "\"";
            //    Inference.frmEditStringParameter frename =
            //        new Inference.frmEditStringParameter(FrameName, header, (Inference.frmMain)Application.OpenForms["frmMain"], Inference.RenamingType.FrameFromEdit);
            //    if (frename.ShowDialog() == DialogResult.OK)
            //    {
            //        FrameName = 
            //    }
            //}
        }

        public int DeleteFrameFromVisual(int frameID, int frameType)
        {
            ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + Directory.GetCurrentDirectory() +
                /*curr_sol_dir*/ "\\Tale.mdf" + ";Integrated Security=True;Connect Timeout=30;User Instance=True";
            conn = new SqlConnection(ConnectionString);
            conn.Open();
            // ПРОВЕРКИ - прописаны в визуале 
            string dn = "";
            if (par.FrameType == 1)
                dn = "Имена фреймов-ситуаций";
            else if (par.FrameType == 2)
                dn = "Имена фреймов-сущностей";
            DeleteFrameFromDomain(frameID, dn);
            DeleteFrame(frameID);
            conn.Close();
            return 0;
        }

        private int DeleteFrame(int frameID)
        {
            int success = 0;
            if (frameID >= 0)
            {
                SqlCommand delete_frame;
                try
                {
                    var slots = from p in Tale.Slot where (p.FrameID == frameID) select p;
                    foreach (Inference.Slot sl in slots)
                    {
                        SlotFrameFuncs.DeleteSlot(sl.ID, Tale);
                    }
                    //delete_frame = new SqlCommand("", conn);
                    //delete_frame.CommandText = "delete from Slot where FrameID=" + frameID;
                    //delete_frame.ExecuteNonQuery();
                    delete_frame = new SqlCommand("", conn);
                    delete_frame.CommandText = "delete from Frame where ID=" + frameID;
                    delete_frame.ExecuteNonQuery();
                }
                catch
                {
                    success = -1;
                    MessageBox.Show("Ошибка при удалении фрейма!", "Ошибка");
                }
            }
            return success;
        }

        private void btn_cancel_Click(object sender, EventArgs e)
        {
            int success = 0;
            if (par.mode == Modes.CREATE_FRAME)
            {
                try
                {
                    string dn = "";
                    if (par.FrameType == 1)
                        dn = "Имена фреймов-ситуаций";
                    else if (par.FrameType == 2)
                        dn = "Имена фреймов-сущностей";
                    DeleteFrameFromDomain(FrameID, dn);
                    success = DeleteFrame(FrameID);
                }
                catch { success = -1; }
            }
            if (success == -1)
                MessageBox.Show("Ошибка отмены создания фрейма!", "Ошибка");
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void LoadSlotToGrid(int ins_i, int slotID, bool if_add)
        {
            if (slotID != -1)
            {
                SqlCommand get_frame_slot = new SqlCommand("", conn);
                get_frame_slot.CommandText = "select * from Slot where ID=" + slotID.ToString();
                sadapt = new SqlDataAdapter(get_frame_slot);
                DataTable datat = new DataTable();
                sadapt.Fill(datat);
                if (if_add)
                    dgSlots.Rows.Insert(ins_i);

                for (int j = 0; j < datat.Columns.Count - 1; j++)
                {
                    DataRow dr = datat.Rows[0];                   
                    for (int i = 0; i < dr.ItemArray.Length; i++)
                    {
                        if (dgSlots.Columns[i].HeaderText == "Допускается ли \"Не знаю\"")
                        {
                            if ((bool)dr.ItemArray[i])
                                dgSlots.Rows[ins_i].Cells[i].Value = "Да";
                            else
                                dgSlots.Rows[ins_i].Cells[i].Value = "Нет";
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Тип наследования")
                        {
                            if ((int)dr.ItemArray[i] == 1)
                                dgSlots.Rows[ins_i].Cells[i].Value = "Override";
                            else
                                dgSlots.Rows[ins_i].Cells[i].Value = "Same";
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Домен")
                        {
                            if (dr.ItemArray[9] != DBNull.Value && (int)dr.ItemArray[9] > 0)
                            {
                                int dom_ind = (int)dr.ItemArray[9];
                                var dom = Tale.Frame.Where(v => v.ID == dom_ind);
                                if (dom.Count() > 0)
                                    dgSlots.Rows[ins_i].Cells[i].Value = dom.First().Name;
                                else
                                    dgSlots.Rows[ins_i].Cells[i].Value = dr.ItemArray[9];
                            }
                            else
                            {
                                int dom_ind = (int)dr.ItemArray[2];
                                var dom = Tale.Domains.Where(v => v.ID == dom_ind);
                                if (dom.Count() > 0)
                                    dgSlots.Rows[ins_i].Cells[i].Value = dom.First().Name;
                                else
                                    dgSlots.Rows[ins_i].Cells[i].Value = dr.ItemArray[2];
                            }
                        }
                        else if (dgSlots.Columns[i].HeaderText == "Задание отсутствия")
                        {
                            int dom_ind = (int)dr.ItemArray[3];
                            if (dr.ItemArray[9] != DBNull.Value && (int)dr.ItemArray[9] > 0)
                            {
                                var def_val = Tale.Frame.Where(v => v.ID == dom_ind);
                                if (def_val.Count() > 0)
                                    dgSlots.Rows[ins_i].Cells[i].Value = def_val.First().Name;
                                else
                                    dgSlots.Rows[ins_i].Cells[i].Value = dr.ItemArray[3];
                            }
                            else
                            {
                                var def_val = Tale.DValues.Where(v => v.ID == dom_ind);
                                if (def_val.Count() > 0)
                                    dgSlots.Rows[ins_i].Cells[i].Value = def_val.First().Value;
                                else
                                    dgSlots.Rows[ins_i].Cells[i].Value = dr.ItemArray[3];
                            }
                        }
                        else
                            dgSlots.Rows[ins_i].Cells[i].Value = dr.ItemArray[i];
                    }

                    Color highlight_color;
                    if (CheckIf.SlotIsInherited(dr.ItemArray[1].ToString(), FrameName))
                        highlight_color = Color.PaleGoldenrod;
                    else
                        highlight_color = Color.PaleGreen;
                    dgSlots.Rows[ins_i].Cells[0].Style.BackColor = highlight_color;
                    dgSlots.Rows[ins_i].Cells[0].Style.ForeColor = highlight_color;
                    Color cl = dgSlots.Rows[ins_i].Cells[0].Style.SelectionBackColor;
                    dgSlots.Rows[ins_i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);

                    //dgSlots.Rows[ins_i].Cells[i].Value = datat.Rows[0].ItemArray[i];
                    if (dr.ItemArray[1].ToString().Trim().ToLower() == "имя фрейма")
                    {
                        dgSlots.Rows[ins_i].Visible = false;
                    }
                }
                Color highl_color;
                if (!CheckIf.SlotIsInherited(datat.Rows[0].ItemArray[1].ToString(), FrameName))
                    highl_color = Color.PaleGreen;
                else
                    highl_color = Color.PaleGoldenrod;
                dgSlots.Rows[ins_i].Cells[0].Style.BackColor = highl_color;
                dgSlots.Rows[ins_i].Cells[0].Style.ForeColor = highl_color;
                Color cl1 = dgSlots.Rows[ins_i].Cells[0].Style.SelectionBackColor;
                dgSlots.Rows[ins_i].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                int u = 0;
                for (int i = dgSlots.Rows.Count - datat.Rows.Count; i < dgSlots.Rows.Count; i++)
                {
                    LoadProducts(slotID, ins_i);
                    u++;
                }
            }
        }

        private void btn_add_slot_Click(object sender, EventArgs e)
        {
            int number = 0, ins_i = 0;
            bool cancel = false;
            if (dgSlots.Rows.Count > 0)
            {
                if (dgSlots.SelectedCells != null && dgSlots.SelectedCells.Count > 0)
                {
                    int sel_ind = dgSlots.SelectedCells[0].RowIndex;
                    if (SystemSlotsCount == 2 && ParentSlotsCount == 1)
                    {
                        ins_i = dgSlots.Rows.Count;
                        number = 1;
                    }
                    else if (sel_ind == dgSlots.Rows.Count - 1
                        && par.FrameType == 1 && dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[1].Value.ToString().ToLower() == "next") // par.FrameType==1
                    {
                        ins_i = dgSlots.Rows.Count - 1;
                        number = datat_frame.Rows.Count - 1;
                    }
                    else if (par.FrameType == 2 && sel_ind >= SystemSlotsCount + ParentSlotsCount - 1)
                    {
                        ins_i = sel_ind + 1;
                        //if (SystemSlotsCount > 0)
                        number = sel_ind - SystemSlotsCount /* - ParentSlotsCount*/ + 1;
                    }           // из-за next
                    else if (par.FrameType == 1 && sel_ind >= SystemSlotsCount + ParentSlotsCount - 2)
                    {
                        ins_i = sel_ind + 1;
                        //if (SystemSlotsCount > 0)
                        number = sel_ind - SystemSlotsCount /* - ParentSlotsCount*/ + 1;
                    }
                    else if (sel_ind < SystemSlotsCount - 1)
                    {
                        cancel = true;
                        MessageBox.Show("Нельзя вставить новый слот между системными слотами!", "Ошибка");
                    }
                    else if (sel_ind >= SystemSlotsCount - 1
                            && sel_ind < SystemSlotsCount + ParentSlotsCount - 1)
                    {
                        cancel = true;
                        MessageBox.Show("Нельзя вставить новый слот между родительскими слотами!", "Ошибка");
                    }
                }
                else
                {
                    if (par.FrameType == 1 && dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[1].Value.ToString().ToLower() == "next")
                    {
                        ins_i = dgSlots.Rows.Count - 1;
                        number = datat_frame.Rows.Count - 1;
                    }
                    else
                    {
                        ins_i = dgSlots.Rows.Count;
                        number = datat_frame.Rows.Count;
                    }
                }
                if (!cancel)
                {
                    slf = new SlotForm(/*ConnectionString,*/ Modes.CREATE_SLOT, par.mode, FrameID, par.FrameType, -1, number, false);
                    DialogResult dr = slf.ShowDialog();
                    if (dr == DialogResult.OK)
                    {
                        SqlCommand get_slot_id = new SqlCommand("", conn);
                        get_slot_id.CommandText = "select max(ID) from Slot";
                        SqlDataReader sread = get_slot_id.ExecuteReader();
                        while (sread.Read())
                        {
                            try
                            {
                                AddedSlotID = sread.GetInt32(0);
                            }
                            catch { }
                        }
                        sread.Close();
                        if (AddedSlotID != -1)
                        {
                            LoadSlotToGrid(ins_i, AddedSlotID, true);
                            datat_frame = LoadSlotsFromDB(conn, FrameID);
                        }
                    }
                }
            }
        }

        private void btn_edit_slot_Click(object sender, EventArgs e)
        {
            if (dgSlots.Rows.Count > 0)
            {
                if (dgSlots.Rows.Count > 0 && dgSlots.SelectedCells.Count > 0 && dgSlots.SelectedRows[0].Cells[1].Value.ToString() != "имя фрейма")
                {
                    int sel_ind = dgSlots.SelectedCells[0].RowIndex;
                    //&& dgSlots.SelectedCells[0].RowIndex >= 0 
                    if (dgSlots.SelectedCells[0].RowIndex >= SystemSlotsCount) // + ParentSlotsCount)
                    {
                        string str = "";
                        bool parent_slot = CheckIf.SlotIsInherited(dgSlots.SelectedRows[0].Cells[1].Value.ToString(), FrameName);
                        // if (!parent_slot)
                        //{
                        //    str = "Вы действительно хотите удалить слот " + dgSlots.SelectedCells[1].Value.ToString() +
                        //               " фрейма " + FrameName + "?";
                        //}
                        //else
                        //{
                        //    str = "Данный слот пронаследован от родительского фрейма! Если его переименовать, фрейм перестанет \n" +
                        //        " наследовать от текущего фрейма-родителя! Вы действительно хотите изменить слот " + dgSlots.SelectedCells[1].Value.ToString() + "?";
                        //}
                        //DialogResult dr = MessageBox.Show(str, "Внимание", MessageBoxButtons.OKCancel);
                        //if (dr == DialogResult.OK)
                        //{
                        slf = new SlotForm(/*ConnectionString,*/ Modes.EDIT_SLOT, mode, FrameID, par.FrameType, int.Parse(dgSlots.SelectedCells[0].Value.ToString()), -1, false);
                        DialogResult dr1 = slf.ShowDialog();
                        if (dr1 == DialogResult.OK)
                        {
                            int UpdatedSlotID = int.Parse(dgSlots.SelectedRows[0].Cells[0].Value.ToString());
                            var slots = Tale.Slot.Where(v => v.ID == UpdatedSlotID);
                            #region не то
                            //SqlCommand get_slot_id = new SqlCommand("", conn);
                            //get_slot_id.CommandText = "select max(ID) from Slot";
                            //SqlDataReader sread = get_slot_id.ExecuteReader();
                            //while (sread.Read())
                            //{
                            //    try
                            //    {
                            //        UpdatedSlotID = sread.GetInt32(0);
                            //    }
                            //    catch { }
                            //}
                            //sread.Close();
                            #endregion
                            if (UpdatedSlotID != -1 && slots.Count() > 0)
                            {
                                bool renamed_slot = dgSlots.SelectedRows[0].Cells[1].Value.ToString() != slots.First().Name;
                                //LoadSlotToGrid(dgSlots.SelectedCells[0].RowIndex, UpdatedSlotID, false);
                                //datat_frame = LoadSlotsFromDB(conn, FrameID);
                                if (renamed_slot)
                                {
                                    string old_root_name = GetRoot(Is_aID).ToLower(), new_root_name = "";
                                    // не ситуация тем же и останется
                                    if (old_root_name == "ситуация")
                                    {
                                        DeleteFrameFromDomain(FrameID, "Имена фреймов-ситуаций");
                                        AddFrameToDomain(FrameID, "Имена фреймов-сущностей");
                                    }
                                    var frames = Tale.Frame.Where(v => v.ID == FrameID);
                                    try
                                    {
                                        Frame frame = frames.First();
                                        frame.Is_a = null;
                                        Tale.SaveChanges();
                                        //SqlCommand delete_isa = new SqlCommand("", conn);
                                        //delete_isa = new SqlCommand("", conn);
                                        //delete_isa.CommandText = "update Frame set Is_a=NULL " +
                                        //    " where ID=" + FrameID.ToString();
                                        //delete_isa.ExecuteNonQuery();
                                    }
                                    catch { }
                                    ParentSlotsCount = 0;
                                }
                                dgSlots.Rows.Clear();
                                datat_frame = LoadSlotsFromDB(conn, FrameID);
                                LoadFrameSlotsToGrid(datat_frame);
                                LoadSystemSlotsToGrid();
                            }
                        }
                        //}
                    }
                    else if (sel_ind == 1 && dgSlots.Rows[sel_ind].Cells[1].Value != null
                          && dgSlots.Rows[sel_ind].Cells[1].Value.ToString().ToLower() == "is a"
                        && FrameName.Trim().ToLower() != "ситуация")
                    {
                        if (Inference.CheckIf.ISACouldBeDeleted(FrameName))
                        {
                            Inference.Is_aForm isaf = new Inference.Is_aForm(FrameID, Tale, conn);
                            if (isaf.ShowDialog() == DialogResult.OK && isaf.IfLinkChanged)
                            {
                                dgSlots.Rows.Clear();
                                ParentSlotsCount = Tale.Slot.Where(s => s.FrameID == Is_aID).Count();
                                datat_frame = LoadSlotsFromDB(conn, FrameID);
                                LoadFrameSlotsToGrid(datat_frame);
                                LoadSystemSlotsToGrid();
                            }
                        }
                        else
                            MessageBox.Show("Связь Is_a не может быть удалена,\n так как слоты " +
                                "данного фрейма или их потомки используются в продукциях!", "Ошибка", MessageBoxButtons.OKCancel);
                    }
                }
            }
        }

        private void UpdateFrame()
        {
            string is_a = (Is_aID >= 0 ? Is_aID.ToString() : "NULL");
            SqlCommand create_frame = new SqlCommand("", conn);
            create_frame.CommandText = "update Frame " +
                "set Name=\'" + FrameName + "\', " +
                "Is_a=" + is_a + "  where ID=" + FrameID.ToString();
            create_frame.ExecuteNonQuery();
        }

        private void AddFrameToDomain(int frameID, string dom_name)
        {
            var frame = Tale.Frame.Where(v => v.ID == frameID);
            try
            {
                string frame_name = frame.First().Name;
                Domains d = Tale.Domains.Where(v => v.Name == dom_name).First();
                DomainsValues domval = new DomainsValues();
                domval.DValues = new DValues();
                domval.DValues.Value = frame_name;
                d.DomainsValues.Add(domval);
                Tale.SaveChanges();
            }
            catch { }

            #region sql
            //SqlCommand create_frame = new SqlCommand("", conn);
            //create_frame.CommandText = "insert into DValues (Value) values (\'" +
            //    FrameName + "\')";
            //create_frame.ExecuteNonQuery();
            //int max_number = -1;
            //SqlCommand get_id = new SqlCommand("", conn);
            //get_id.CommandText = "select max(Number) from DomainsValues where DomID=" + dom_id.ToString();
            //SqlDataReader sread = get_id.ExecuteReader();
            //while (sread.Read())
            //{
            //    try
            //    {
            //        max_number = sread.GetInt32(0);
            //    }
            //    catch { }
            //}
            //sread.Close();
            //int val_id = GetMaxTableID("DValues");
            //create_frame.CommandText = "insert into DomainsValues (Value, DomID, Number) values (" +
            //    val_id.ToString() + ", " + dom_id.ToString() + ", " + (max_number + 1).ToString() + ")";
            //create_frame.ExecuteNonQuery();
            #endregion
        }


        public void DeleteFrameFromDomain(int frameID, string dom_name)
        {
            //string dn = "";
            var frame = Tale.Frame.Where(v => v.ID == frameID);
            try
            {
                string frame_name = frame.First().Name;
                Inference.frmMain frf = (Inference.frmMain)Application.OpenForms["frmMain"];
                Domains dom = frf.getDomainByName(dom_name, Tale);
                var domvals = dom.DomainsValues.Where(d => d.DValues.Value == frame_name);
                try
                {
                    var domval = domvals.First();
                    DValues dv1 = domval.DValues;
                    Tale.DeleteObject(domval);
                    Tale.DeleteObject(dv1);
                    Tale.SaveChanges();
                    frf.RefreshDomainNodes(dom, dom_name);
                }
                catch { }
            }
            catch { }
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            // if par.mode==Modes.create_frame frame's already created
            // откат в случае отмены
            if (par.mode == Modes.EDIT_FRAME) //- НЕ записывать координаты в базу !
                UpdateFrame();
            else if (par.mode == Modes.CREATE_FRAME)
            {
                string dn = "";
                if (par.FrameType == 1)
                    dn = "Имена фреймов-ситуаций";
                else if (par.FrameType == 2)
                    dn = "Имена фреймов-сущностей";
                AddFrameToDomain(FrameID, dn);
            }
            this.DialogResult = DialogResult.OK;
            this.Close();
            // FrameSlots.Clear();
        }

        private void dgSlots_SelectionChanged(object sender, EventArgs e)
        {
            if (dgSlots.SelectedCells != null && dgSlots.SelectedCells.Count > 0)
            {
                int row_index = dgSlots.SelectedCells[0].RowIndex;
                if (dgSlots.SelectedCells[0].Value == null)   // system slots
                    btn_del_slot.Enabled = false;
                else if (par.FrameType == 1 && (FrameName.Trim().ToLower() == "ситуация" &&
                    dgSlots.SelectedCells[1].Value.ToString().ToLower() == "next"))
                    btn_del_slot.Enabled = false;
                //else if (par.FrameType == 1 &&
                //        row_index >= SystemSlotsCount    // parent slot
                //        && row_index < SystemSlotsCount + ParentSlotsCount
                //        && dgSlots.Rows.Count == SystemSlotsCount + ParentSlotsCount)
                //    btn_del_slot.Enabled = false;
                //else if (par.FrameType == 2 && row_index >= SystemSlotsCount &&    // parent slot
                //       row_index < SystemSlotsCount + ParentSlotsCount)
                //    btn_del_slot.Enabled = false;
                //else if (par.FrameType == 1 && row_index >= SystemSlotsCount &&    // parent slot
                //   row_index < SystemSlotsCount + ParentSlotsCount - 1)
                //    btn_del_slot.Enabled = false;
                //else if (par.FrameType == 2 && dgSlots.SelectedCells[1].Value.ToString().ToLower() == "имя")
                //    btn_del_slot.Enabled = false;
                else
                    btn_del_slot.Enabled = true;
            }
            else
                btn_del_slot.Enabled = false;
        }

        private void dgSlots_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex > -1 && e.RowIndex < dgSlots.Rows.Count && e.RowIndex >= SystemSlotsCount
                && dgSlots.Rows[e.RowIndex].Cells[0].Style.BackColor == Color.PaleGreen)// + ParentSlotsCount)
            {
                dragged_row_index = e.RowIndex;
            }
        }

        private void dgSlots_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (dragged_row_index != -1 && e.RowIndex != dragged_row_index && e.RowIndex != -1
                && dragged_row_index < dgSlots.Rows.Count && e.RowIndex < dgSlots.Rows.Count
                /* && e.RowIndex >= SystemSlotsCount + ParentSlotsCount && dragged_row_index >= SystemSlotsCount + ParentSlotsCount*/
               && dgSlots.Rows[dragged_row_index].Cells[0].Style.BackColor == Color.PaleGreen
               && dgSlots.Rows[e.RowIndex].Cells[0].Style.BackColor == Color.PaleGreen
                && dgSlots.Rows[dragged_row_index].Cells[1].Value.ToString().ToLower() != "next"
                && dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString().ToLower() != "next"
                && dgSlots.Rows[dragged_row_index].Cells[1].Value.ToString().ToLower() != "имя фрейма"
                && dgSlots.Rows[e.RowIndex].Cells[1].Value.ToString().ToLower() != "имя фрейма")
            {
                Inference.LV lv = new Inference.LV(ConnectionString);
                bool cancel = false;
                int[] id_number_old = new int[4];
                id_number_old[0] = (int)dgSlots.Rows[dragged_row_index].Cells[0].Value; // id  dragged
                id_number_old[1] = (int)dgSlots.Rows[dragged_row_index].Cells[7].Value; // number  dragged

                id_number_old[2] = (int)dgSlots.Rows[e.RowIndex].Cells[0].Value; // id
                id_number_old[3] = (int)dgSlots.Rows[e.RowIndex].Cells[7].Value; // number
                bool res_dr = true, res_dest = true;
                int ind1 = -1, ind2 = -1;
                if (e.RowIndex > dragged_row_index)
                {
                    // e.rowindex, e.rowindex-1
                    ind1 = e.RowIndex; ind2 = e.RowIndex - 1;
                }
                else if (e.RowIndex < dragged_row_index)
                {
                    ind1 = e.RowIndex; ind2 = e.RowIndex + 1;
                }

                // чтобы продукции проверять
                SqlCommand update_num_1 = new SqlCommand("", conn);
                update_num_1.CommandText = "update Slot set Number=" +
                    dgSlots.Rows[ind2].Cells[7].Value.ToString() +
                    " where ID=" + dgSlots.Rows[ind1].Cells[0].Value.ToString();
                update_num_1.ExecuteNonQuery();
                SqlCommand update_num_2 = new SqlCommand("", conn);
                update_num_2.CommandText = "update Slot set Number=" +
                    dgSlots.Rows[ind1].Cells[7].Value.ToString() +
                    " where ID=" + dgSlots.Rows[ind2].Cells[0].Value.ToString();
                update_num_2.ExecuteNonQuery();

                try
                {
                    int dragged_id = (int)dgSlots.Rows[ind1].Cells[0].Value;
                    Inference.Slot def_val_id = Tale.Slot.Where(v => v.ID == dragged_id).First();
                    if (def_val_id.DefaultValue != null)
                        res_dr = lv.CheckSlotValue1(id_number_old[0], (int)def_val_id.DefaultValue);
                    else
                        res_dest = true;
                }
                catch
                { res_dr = false; }
                try
                {
                    int dest_id = (int)dgSlots.Rows[ind2].Cells[0].Value;
                    Inference.Slot def_val_id = Tale.Slot.Where(v => v.ID == dest_id).First();
                    if (def_val_id.DefaultValue != null)
                        res_dest = lv.CheckSlotValue1(id_number_old[3], (int)def_val_id.DefaultValue);
                    else
                        res_dest = true;
                }
                catch
                { res_dest = false; }

                string str = "";
                if (!res_dr)
                {
                    str = "После изменения местоположения слота " +
                        dgSlots.Rows[ind1].Cells[1].Value.ToString() + " его маркеры не будут срабатывать! Продолжить?\n";
                }
                else if (!res_dest)
                    str = "После изменения местоположения слота " +
                        dgSlots.Rows[ind2].Cells[1].Value.ToString() + " его маркеры не будут срабатывать! Продолжить?\n";
                if (str != "")
                    if (MessageBox.Show(str, "Внимание", MessageBoxButtons.YesNo) == DialogResult.No)
                        cancel = true;
                // -------------------------------------------
                if (!cancel)
                {
                    if (e.RowIndex > dragged_row_index)
                    {
                        dgSlots.Rows.Insert(e.RowIndex + 1);
                        for (int i = 0; i < dgSlots.Columns.Count; i++)
                        {
                            dgSlots.Rows[e.RowIndex + 1].Cells[i].Value = dgSlots.Rows[dragged_row_index].Cells[i].Value;
                            //dgSlots.Rows[e.RowIndex].Cells[i].Value = dgSlots.Rows[dragged_row_index].Cells[i].Value;
                        }
                        dgSlots.Rows[e.RowIndex + 1].Cells[0].Style.BackColor = Color.PaleGreen;
                        dgSlots.Rows[e.RowIndex + 1].Cells[0].Style.ForeColor = Color.PaleGreen;
                        Color cl = dgSlots.Rows[e.RowIndex + 1].Cells[0].Style.SelectionBackColor;
                        dgSlots.Rows[e.RowIndex + 1].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                        dgSlots.Rows.RemoveAt(dragged_row_index);
                    }
                    else if (e.RowIndex < dragged_row_index)
                    {
                        dgSlots.Rows.Insert(e.RowIndex);
                        for (int i = 0; i < dgSlots.Columns.Count; i++)
                        {
                            dgSlots.Rows[e.RowIndex].Cells[i].Value = dgSlots.Rows[dragged_row_index + 1].Cells[i].Value;
                        }
                        dgSlots.Rows[e.RowIndex].Cells[0].Style.BackColor = Color.PaleGreen;
                        dgSlots.Rows[e.RowIndex].Cells[0].Style.ForeColor = Color.PaleGreen;
                        Color cl = dgSlots.Rows[e.RowIndex].Cells[0].Style.SelectionBackColor;
                        dgSlots.Rows[e.RowIndex].Cells[0].Style.SelectionForeColor = Color.FromArgb(51, 153, 255);
                        dgSlots.Rows.RemoveAt(dragged_row_index + 1);
                    }
                    dgSlots.Rows[e.RowIndex].Selected = true;
                }
                else
                {
                    update_num_1 = new SqlCommand("", conn);
                    update_num_1.CommandText = "update Slot set Number=" +
                        dgSlots.Rows[ind1].Cells[7].Value.ToString() +
                        " where ID=" + dgSlots.Rows[ind2].Cells[0].Value.ToString();
                    update_num_1.ExecuteNonQuery();
                    update_num_2 = new SqlCommand("", conn);
                    update_num_2.CommandText = "update Slot set Number=" +
                        dgSlots.Rows[ind2].Cells[7].Value.ToString() +
                        " where ID=" + dgSlots.Rows[ind1].Cells[0].Value.ToString();
                    update_num_2.ExecuteNonQuery();
                }
            }
        }



        public int RecursDeleteSlot(int slotID)
        {
            int success = 0;
            if (slotID >= 0)
            {
                string slot_name = Tale.Slot.Where(v => v.ID == slotID).First().Name;
                //DeleteSlot(slotID);
                //List<Inference.Frame> children = Inference.CheckIf.ChildrenOf(frameName, true, tale);
                List<Slot> deleted_slots = CheckIf.SlotsNamedLike(slot_name, FrameName, Tale);
                for (int i = 0; i < deleted_slots.Count; i++)
                {
                    try
                    {
                        SlotFrameFuncs.DeleteSlot(deleted_slots[i].ID, Tale);
                    }
                    catch { MessageBox.Show("Ошибка удаления слота!", "Ошибка"); success = -1; }
                }
                //for (int j = 0; j < children.Count; j++)
                //{
                //    var slot = tale.Slot.Where(v => v.Name == slot_name && v.FrameID == children[j].ID);
                //    if (slot.Count()>0)
                //    {
                //        int slot_id = slot.First().ID;
                //        DeleteSlot(slot_id);
                //    }
                //}
                return success;
            }
            else
                return -1;

            //int success = 0;
            //if (slotID >= 0)
            //{
            //    string slot_name = Tale.Slot.Where(v => v.ID == slotID).First().Name;
            //    SlotFrameFuncs.DeleteSlot(slotID, Tale);
            //    List<Inference.Frame> children = Inference.CheckIf.ChildrenOf(FrameName, true, Tale);
            //    for (int j = 0; j < children.Count; j++)
            //    {
            //        var slot = Tale.Slot.Where(v => v.Name == slot_name && v.FrameID == children[j].ID);
            //        //if (slot != null)
            //        try
            //        {
            //            int slot_id = slot.First().ID;
            //            SlotFrameFuncs.DeleteSlot(slot_id, Tale);
            //        }
            //        catch
            //        { MessageBox.Show("Ошибка удаления слота!", "Ошибка"); success = -1; }
            //    }
            //    return success;
            //}
            //return success;
        }

        //private void ReindexSlots(int frameID)   // numbers
        //{
        //    var slots = Tale.Slot.Where(v => v.FrameID == frameID);
        //    int i = 0;
        //    foreach (Inference.Slot sl in slots)
        //    {
        //        try
        //        {
        //            SqlCommand update_slot = new SqlCommand("", conn);
        //            update_slot.CommandText =
        //                "update Slot set Number=" + i.ToString() +
        //                " where ID=" + frameID.ToString();
        //            update_slot.ExecuteNonQuery();
        //        }
        //        catch { }
        //        i++;
        //    }
        //}

        string GetRoot(int FrameID)
        {
            Frame fr;
            do
            {
                fr = Tale.Frame.Where(f => f.ID == FrameID).First();
                if (fr.Is_a.HasValue)
                    FrameID = fr.Is_a.Value;
                else
                    FrameID = 0;
            }
            while (FrameID != 0);
            return fr.Name;
        }

        private void btn_del_slot_Click(object sender, EventArgs e)
        {
            if (dgSlots.Rows.Count > 0)
            {
                if (dgSlots.SelectedCells != null && dgSlots.SelectedCells.Count > 0)
                {
                    int row_index = dgSlots.SelectedCells[0].RowIndex;
                    bool cancel = false, parent_slot = false;
                    if (dgSlots.SelectedCells[0].Value == null || dgSlots.SelectedRows[0].Cells[1].Value.ToString() == "имя фрейма")
                    {
                        MessageBox.Show("Нельзя удалить системный слот!", "Ошибка");
                        cancel = true;
                    }

                    else if (par.FrameType == 1 && dgSlots.SelectedCells[1].Value.ToString().ToLower() == "next")
                    {
                        //  MessageBox.Show("Нельзя удалить родительский слот!", "Ошибка");
                        //cancel = true; 
                        parent_slot = true;
                    }
                    else if (par.FrameType == 1 && row_index >= SystemSlotsCount    // parent slot
                            && row_index < SystemSlotsCount + ParentSlotsCount
                            && dgSlots.Rows.Count == SystemSlotsCount + ParentSlotsCount)
                    {
                        // MessageBox.Show("Нельзя удалить родительский слот!", "Ошибка");
                        //cancel = true;
                        parent_slot = true;
                    }
                    else if (par.FrameType == 2 && row_index >= SystemSlotsCount &&    // parent slot
                           row_index < SystemSlotsCount + ParentSlotsCount)
                    {
                        //MessageBox.Show("Нельзя удалить родительский слот!", "Ошибка");
                        //cancel = true;
                        parent_slot = true;
                    }
                    else if (par.FrameType == 1 && row_index >= SystemSlotsCount &&    // parent slot
                       row_index < SystemSlotsCount + ParentSlotsCount - 1)
                    {
                        //MessageBox.Show("Нельзя удалить родительский слот!", "Ошибка");
                        //cancel = true;
                        parent_slot = true;
                    }

                    // if (dgSlots.SelectedCells != null && dgSlots.SelectedCells.Count > 0)
                    if (!cancel)
                    {

                        string str = "";
                        if (Inference.CheckIf.SlotIsInUse((string)dgSlots.SelectedCells[1].Value, FrameName))
                        {
                            str = "Нельзя удалить слот " + dgSlots.SelectedCells[1].Value.ToString() +
                                   " фрейма" + FrameName + " - он используется в продукциях!"; // слотов: \n";
                            //for (int i = 0; i < length; i++)
                            MessageBox.Show(str, "Ошибка");
                        }
                        else
                        {
                            //   if (!parent_slot)
                            {
                                str = "Вы действительно хотите удалить слот " + dgSlots.SelectedCells[1].Value.ToString() +
                                           " фрейма " + FrameName + "?";
                            }
                            //else
                            //{
                            //    str = "Данный слот пронаследован от родительского фрейма! Если его удалить, фрейм перестанет \n" +
                            //        " наследовать от текущего фрейма-родителя! Вы действительно хотите удалить слот " + dgSlots.SelectedCells[1].Value.ToString() + "?";
                            //}
                            DialogResult dr = MessageBox.Show(str, "Внимание", MessageBoxButtons.OKCancel);
                            if (dr == DialogResult.OK)
                            {
                                int del_number = (int)dgSlots.SelectedCells[7].Value, num_in_datat_frame = -1;
                                int del_success = RecursDeleteSlot((int)dgSlots.SelectedCells[0].Value);
                                for (int i = 0; i < datat_frame.Rows.Count; i++)
                                    if ((int)datat_frame.Rows[i].ItemArray[0] == (int)dgSlots.SelectedCells[0].Value)
                                    {
                                        num_in_datat_frame = i;
                                    }
                                if (del_success >= 0 && num_in_datat_frame >= 0)
                                {
                                    datat_frame.Rows.RemoveAt(num_in_datat_frame);
                                    SlotFrameFuncs.ReindexSlots(FrameID);//, Tale);
                                    // dgSlots.Rows.RemoveAt(dgSlots.SelectedCells[0].RowIndex);

                                    if (parent_slot)
                                    {
                                        string old_root_name = GetRoot(Is_aID).ToLower(), new_root_name = "";
                                        // не ситуация тем же и останется
                                        if (old_root_name == "ситуация")
                                        {
                                            SlotFrameFuncs.DeleteSlot((int)dgSlots.Rows[dgSlots.Rows.Count - 1].Cells[0].Value,Tale);
                                            DeleteFrameFromDomain(FrameID, "Имена фреймов-ситуаций");
                                            AddFrameToDomain(FrameID, "Имена фреймов-сущностей");
                                        }
                                        var frames = Tale.Frame.Where(v => v.ID == FrameID);
                                        try
                                        {
                                            Frame frame = frames.First();
                                            frame.Is_a = null;
                                            Tale.SaveChanges();
                                            //SqlCommand delete_isa = new SqlCommand("", conn);
                                            //delete_isa = new SqlCommand("", conn);
                                            //delete_isa.CommandText = "update Frame set Is_a=NULL " +
                                            //    " where ID=" + FrameID.ToString();
                                            //delete_isa.ExecuteNonQuery();
                                        }
                                        catch { }
                                        ParentSlotsCount = 0;
                                    }
                                    dgSlots.Rows.Clear();
                                    datat_frame = LoadSlotsFromDB(conn, FrameID);
                                    LoadFrameSlotsToGrid(datat_frame);
                                    LoadSystemSlotsToGrid();
                                }
                            }
                        }
                    }
                }
            }
        }


    }
}
